package com.cj.library.widget.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.InputFilter;
import android.text.InputType;
import android.util.AttributeSet;
import android.widget.EditText;

import com.cj.library.widget.R;

/**
 * Created by JiangGe on 2016/9/2.
 */
public class FormatEditText extends EditText {

    public static final int INPUT_TYPE_BANK_CARD = 1;//bankcard
    public static final int INPUT_TYPE_TEL_NUM = 2;//phonenum

    private static final int MAX_LENGTH_BANK_CARD = 19;
    private static final int MAX_LENGTH_TEL_NUM = 11;
    private static final String DEFAULT_SPILT_CHAR = " ";//default spilt char

    private String spiltChar = DEFAULT_SPILT_CHAR;//spilt char
    private int spiltCharColor = Color.BLACK;//spilt color
    private Paint spiltPaint;
    private int textLength;

    /**
     * 0：common
     * 1：bankcard,
     * 2: phonenum
     */
    private int formatType;//1:true,0:false.

    public FormatEditText(Context context) {
        super(context);
    }

    public FormatEditText(Context context, AttributeSet attrs) {
        super(context, attrs);

        spiltPaint = new Paint(getPaint());

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FormatEditText);
        int input = a.getInt(R.styleable.FormatEditText_formatType, 0);
        spiltChar = a.getString(R.styleable.FormatEditText_spiltChar);
        spiltPaint.setColor(a.getColor(R.styleable.FormatEditText_spiltColor, getPaint().getColor()));
        spiltPaint.setTextSize(a.getDimension(R.styleable.FormatEditText_spiltSize, getPaint().getTextSize()));
        if (spiltChar == null) {
            spiltChar = DEFAULT_SPILT_CHAR;
        }

        formatType = input;

        switch (input) {
            case INPUT_TYPE_BANK_CARD://bankcard
                textLength = a.getInt(R.styleable.FormatEditText_textLength, MAX_LENGTH_BANK_CARD);
                setFilters(new InputFilter.LengthFilter[]{new InputFilter.LengthFilter(textLength)});
                setInputType(InputType.TYPE_CLASS_NUMBER);
                break;
            case INPUT_TYPE_TEL_NUM://phone
                textLength = a.getInt(R.styleable.FormatEditText_textLength, MAX_LENGTH_TEL_NUM);
                setFilters(new InputFilter.LengthFilter[]{new InputFilter.LengthFilter(textLength)});
                setInputType(InputType.TYPE_CLASS_NUMBER);
                break;
        }

        a.recycle();
    }

    /**
     * get bank num
     *
     * @return 银行卡号
     */
    public String getBankcard() {
        if (formatType == INPUT_TYPE_BANK_CARD) {
            return getText().toString();
        }

        return null;
    }

    /**
     * get phone num
     *
     * @return 电话号码
     */
    public String getTelNum() {
        if (formatType == INPUT_TYPE_TEL_NUM) {
            return getText().toString();
        }
        return null;
    }

    public FormatEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
        String content = getText().toString();
        float x = getPaddingLeft();
        Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
        float textY = getMeasuredHeight() / 2 + Math.abs((fontMetrics.ascent + fontMetrics.descent) / 2);

        Paint.FontMetrics splitMetrics = spiltPaint.getFontMetrics();
        float splitY = getMeasuredHeight() / 2 + Math.abs((splitMetrics.ascent + splitMetrics.descent) / 2);

        canvas.save();
        canvas.translate(x, 0);
        int count = 0;
        switch (formatType) {
            case INPUT_TYPE_BANK_CARD://bank
                count = content.length() % 4 == 0 ? content.length() / 4 : content.length() / 4 + 1;
                for (int i = 0; i < count; i++) {
                    String sub = content.substring(4 * i, 4 * (i + 1) > content.length() ? content.length() : 4 * (i + 1));
                    canvas.drawText(sub, 0, textY, getPaint());
                    canvas.translate(getPaint().measureText(sub), 0);
                    if (i < count - 1) {
                        canvas.drawText(spiltChar, 0, splitY, spiltPaint);
                        canvas.translate(spiltPaint.measureText(spiltChar), 0);
                    }
                }
                break;
            case INPUT_TYPE_TEL_NUM://phone
                if (content.length() < 3) {
                    count = 1;
                } else {
                    count = 1 + ((content.length() - 3) % 4 == 0 ? (content.length() - 3) / 4 : (content.length() - 3) / 4 + 1);
                }
                for (int i = 0; i < count; i++) {
                    String sub = "";
                    int index = 0;
                    if (i == 0) {
                        index = 3;
                        sub = content.substring(0, index > content.length() ? content.length() : index);
                    } else {
                        index = 3 + i * 4;
                        sub = content.substring(3 + (i - 1) * 4, index > content.length() ? content.length() : index);
                    }
                    canvas.drawText(sub, 0, textY, getPaint());
                    canvas.translate(getPaint().measureText(sub), 0);

                    if (i < count - 1) {
                        canvas.drawText(spiltChar, 0, splitY, spiltPaint);
                        canvas.translate(spiltPaint.measureText(spiltChar), 0);
                    }
                }
                break;
            default:
                canvas.drawText(content, x, textY, getPaint());
        }
        canvas.restore();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measuredWidth(widthMeasureSpec);
        int height = measuredHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int measuredHeight(int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = 0;
        switch (mode) {
            case MeasureSpec.EXACTLY:
                size = MeasureSpec.getSize(heightMeasureSpec);
                break;
            case MeasureSpec.AT_MOST:
                Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
                size = (int) (fontMetrics.bottom - fontMetrics.top + getPaddingTop() + getPaddingBottom());
                break;
        }
        return size;
    }

    private int measuredWidth(int widthMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = 0;
        switch (mode) {
            case MeasureSpec.EXACTLY:
                size = MeasureSpec.getSize(widthMeasureSpec);
                break;
            case MeasureSpec.AT_MOST:
                switch (formatType) {
                    case INPUT_TYPE_BANK_CARD://bank
                        size = (int) Math.round(textLength * getPaint().measureText("0") + spiltPaint.measureText(spiltChar) * 3 + 0.5) + getPaddingLeft() + getPaddingRight();
                        break;
                    case INPUT_TYPE_TEL_NUM://phone
                        size = (int) (textLength * getPaint().measureText("0") + spiltPaint.measureText(spiltChar) * 2) + getPaddingLeft() + getPaddingRight();
                        break;
                    default:
                        size = (int) Math.round(getPaint().measureText(getText().toString()) + 0.5) + getPaddingLeft() + getPaddingRight();
                }
                break;
        }
        return size;
    }


    public void setSpiltChar(String spiltChar) {
        this.spiltChar = spiltChar;
        invalidate();
    }

    public void setSpiltCharColor(int spiltCharColor) {
        this.spiltCharColor = spiltCharColor;
        invalidate();
    }

    public void setFormatType(int formatType) {
        this.formatType = formatType;
    }
}
